package com.welink.cmp.meatdata.service;

import com.welink.base.statemachine.StateMachine;
import com.welink.base.statemachine.StateMachineFactory;
import com.welink.cmp.convertor.GenericConvertor;
import com.welink.cmp.dao.metadata.dataobject.FirewallDO;
import com.welink.cmp.domain.metadata.enums.ResourceTypeEnum;
import com.welink.cmp.dto.metadata.DestroyUpdateCmd;
import com.welink.cmp.dto.metadata.MetadataIdListQry;
import com.welink.cmp.dto.metadata.firewall.*;

import com.welink.cmp.dto.metadata.firewall.clientobject.FirewallCO;
import com.welink.cmp.dto.metadata.firewall.query.FirewallListByPageQry;
import com.welink.cmp.meatdata.command.FirewallCmdExe;
import com.welink.cmp.statemachine.StateMachineIdContent;
import com.welink.cmp.statemachine.context.CommonCtx;
import com.welink.cmp.statemachine.machine.CommonEvent;
import com.welink.cmp.statemachine.machine.CommonState;
import com.welink.common.dto.PageResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * Firewall应用服务类
 * 提供Firewall相关的操作接口
 */
@Service
public class FirewallAppService {

    @Autowired
    private FirewallCmdExe firewallCmdExe;


    /**
     * 添加Firewall
     *
     * @param addCmd 添加Firewall的命令对象
     * @return 新增Firewall的ID
     */
    public Long addFirewall(CreateFirewallAddCmd addCmd) {
        final FirewallDO firewallDO = firewallCmdExe.checkExistByName(addCmd.getName());
        if (firewallDO != null){
            return firewallDO.getId();
        }
        return firewallCmdExe.save(addCmd);
    }

    /**
     * 配置Firewall基础信息
     *
     * @param setupBaseCmd 配置Firewall基础信息的命令对象
     * @return 配置是否成功
     */
    public Boolean setupFirewallBase(SetupFwBaseUpdateCmd setupBaseCmd) {
        final FirewallDO updateDO = GenericConvertor.toDO(setupBaseCmd, FirewallDO.class);
        if (setupBaseCmd.isNeedsOperator()) {
            updateDO.setUpdateBy(setupBaseCmd.getOperator());
        }
        return firewallCmdExe.update(updateDO);
    }
    /**
     * 配置Firewall机房信息
     *
     * @param setupRackCmd 配置Firewall网络信息的命令对象
     * @return 配置是否成功
     */
    public Boolean setupFirewallRack(SetupFwRackUpdateCmd setupRackCmd) {
        final FirewallDO updateDO = GenericConvertor.toDO(setupRackCmd, FirewallDO.class);
        if (setupRackCmd.isNeedsOperator()) {
            updateDO.setUpdateBy(setupRackCmd.getOperator());
        }
        return firewallCmdExe.update(updateDO);
    }
    /**
     * 配置Firewall网络信息
     *
     * @param setupNetCmd 配置Firewall网络信息的命令对象
     * @return 配置是否成功
     */
    public Boolean setupFirewallNet(SetupFwNetUpdateCmd setupNetCmd) {
        final FirewallDO updateDO = GenericConvertor.toDO(setupNetCmd, FirewallDO.class);
        if (setupNetCmd.isNeedsOperator()) {
            updateDO.setUpdateBy(setupNetCmd.getOperator());
        }
        return firewallCmdExe.update(updateDO);
    }

    /**
     * 上架Firewall
     *
     * @param launchFwUpdCmd 上架Firewall的命令对象
     * @return 上架是否成功
     */
    public Boolean launchFirewall(LaunchFirewallUpdateCmd launchFwUpdCmd) {
        StateMachine<CommonState, CommonEvent, CommonCtx> stateMachine = StateMachineFactory.get(StateMachineIdContent.common_state_machine_id);
        CommonCtx ctx = CommonCtx.builder()
                .id(launchFwUpdCmd.getId())
                .operator(launchFwUpdCmd.getOperator())
                .typeEnum(ResourceTypeEnum.FIREWALL)
                .launchedTime(launchFwUpdCmd.getLaunched_time())
                .build();
        final CommonState state = stateMachine.fireEvent(CommonState.NEW, CommonEvent.MOUNTED, ctx);
        return CommonState.IDLE.getCode() == state.getCode();
    }

    /**
     * 下架Firewall
     *
     * @param updateCmd 下架Firewall的命令对象
     * @return 下架是否成功
     */
    public Boolean shutdownFirewall(ShutdownFirewallUpdateCmd updateCmd) {
        StateMachine<CommonState, CommonEvent, CommonCtx> stateMachine = StateMachineFactory.get(StateMachineIdContent.common_state_machine_id);
        CommonCtx ctx = CommonCtx.builder()
                .id(updateCmd.getId())
                .typeEnum(ResourceTypeEnum.FIREWALL)
                .operator(updateCmd.getOperator())
                .build();
        final CommonState state = stateMachine.fireEvent(CommonState.IDLE, CommonEvent.UNMOUNTED,ctx);
        return CommonState.IDLE.getCode() == state.getCode();
    }


    /**
     * 报废Firewall
     *
     * @param destroyUpdCmd 报废Firewall的命令对象
     * @return 报废是否成功
     */
    public Boolean destroyFirewall(DestroyUpdateCmd destroyUpdCmd){
        StateMachine<CommonState, CommonEvent, CommonCtx> stateMachine = StateMachineFactory.get(StateMachineIdContent.common_state_machine_id);
        CommonCtx ctx = CommonCtx.builder()
                .id(destroyUpdCmd.getId())
                .typeEnum(ResourceTypeEnum.FIREWALL)
                .operator(destroyUpdCmd.getOperator())
                .build();
        final CommonState state = stateMachine.fireEvent(CommonState.RETIRED, CommonEvent.EXPIRED, ctx);
        return CommonState.IDLE.getCode() == state.getCode();
    }


    /**
     * 根据ID获取Firewall
     *
     * @param id Firewall ID
     * @return Firewall业务对象
     */
    public FirewallCO getFirewallById(Long id) {
        return firewallCmdExe.queryById(id);
    }

    /**
     * 列表查询Firewall
     *
     * @param listQry 列表查询条件
     * @return Host业务对象列表
     */
    public List<FirewallCO> hostListQuery(MetadataIdListQry listQry) {
        return firewallCmdExe.listQuery(listQry);
    }

    /**
     * 分页查询Firewall
     *
     * @param pageQry 分页查询条件
     * @return 分页响应，包括Host列表和分页信息
     */
    public PageResponse<FirewallCO> firewallPageQuery(FirewallListByPageQry pageQry) {
        return firewallCmdExe.pageQuery(pageQry);
    }
}